﻿using System;
using System.Collections.Generic;
using System.Text;

namespace FySystem.Converter
{
    /// <summary>
    /// 进制转换
    /// </summary>
    public class NumberConversion
    {
        /// <summary>
        /// 字节数组转短整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static short BytesToShort(byte[] data)
        {
            short res = -1;
            try
            {
                res = BitConverter.ToInt16(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 字节数组转无符号短整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static ushort BytesToUShort(byte[] data)
        {
            ushort res = 0;
            try
            {
                res = BitConverter.ToUInt16(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static int BytesToInt(byte[] data)
        {
            int res = -1;
            try
            {
                res = BitConverter.ToInt32(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转浮点
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static float BytesToFloat(byte[] data)
        {
            float res = -1;
            try
            {
                res = BitConverter.ToSingle(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转无符号整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static uint BytesToUInt(byte[] data)
        {
            uint res = 0;
            try
            {
                res = BitConverter.ToUInt32(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转长整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static long BytesToLong(byte[] data)
        {
            long res = -1;
            try
            {
                res = BitConverter.ToInt64(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转无符号长整型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static ulong BytesToULong(byte[] data)
        {
            ulong res = 0;
            try
            {
                res = BitConverter.ToUInt64(data, 0);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 16进制字符串转byte
        /// </summary>
        /// <param name="sub"></param>
        /// <returns></returns>
        public static byte HexStringToByte(string hexString)
        {
            byte res = 0x00;
            try
            {
                hexString = hexString.PadLeft(2, '0');
                res = Convert.ToByte(hexString, 16);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 16进制字符串转byte
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string hexString)
        {
            byte[] res = null;
            try
            {
                if (hexString.Length % 2 != 0)
                    hexString = '0' + hexString;

                int length = hexString.Length / 2;
                res= new byte[length];
                for(int i = 0; i < length; i++)
                {
                    res[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// byte数组转16进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <param name="whiteSpace"></param>
        /// <returns></returns>
        public static string BytesToHexString(byte[] data, int offset, int count, bool whiteSpace)
        {
            StringBuilder res = new StringBuilder();
            try
            {
                if (data != null)
                {
                    for (int i = offset; i < offset + count; i++)
                    {
                        if (i > offset && whiteSpace)
                            res.Append(' ');
                        res.Append(data[i].ToString("X2"));
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res.ToString();
        }

        /// <summary>
        /// 以无空格的方式将字节数组转换为十六进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string BytesToHexString(Span<byte> data)
        {
            StringBuilder res = new StringBuilder();
            try
            {
                if (data != null)
                {
                    for(int i = 0; i < data.Length; i++)
                    {
                        res.Append(data[i].ToString("X2"));
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res.ToString();
        }

        /// <summary>
        /// byte数组转二进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string BytesToBinaryString(byte[] data)
        {
            StringBuilder res = new StringBuilder();
            try
            {
                for (int i = 0; i < data.Length; i++)
                {
                    string binary = Convert.ToString(data[i], 2);
                    if (binary.Length < 8)
                    {
                        for (int j = 0; j < 8 - binary.Length; j++)
                        {
                            res.Append("0");
                        }
                    }
                    res.Append(binary);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res.ToString();
        }

        /// <summary>
        /// 将数组转换为2进制，每个byte代表一个bit，2022-08-04修复bug
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] BytesToBinary(byte[] data)
        {
            byte[] res = new byte[data.Length * 8];
            try
            {
                byte b = data[0];

                for (int i = 0; i < res.Length; i++)
                {
                    if (i % 8 == 0)
                        b = data[i / 8];

                    res[i] = (byte)(b & 0x01);
                    b = (byte)(b >> 1);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }
    }
}
